#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QFile>
#include <QIODevice>
#include <QMessageBox>
#include <QDebug>
#include <QTextCodec>
#include <QFileDialog>
#include <QAction>
#include <QTextBlock>
#include <QRegExp>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    initView();
}

MainWindow::~MainWindow()
{
    delete ui;
    delete m_aboutWindow;
    delete m_objectWindow;
}

void MainWindow::initView()
{
    //设置主窗口标题
    setWindowTitle(QString("%1 %2").arg(MAIN_WINDOW_TITLE, SYSTEM_VERSION));
    //重置窗口大小
    resize(1200, 800);
    //设置最大化显示
    //showMaximized();
    //连接信号和槽
    connect(ui->actionopen, &QAction::triggered, this, &MainWindow::openObjectFile);
    connect(ui->actionnew, &QAction::triggered, this, &MainWindow::newObjectFile);
    connect(ui->actionclose, &QAction::triggered, this, &MainWindow::closeObjectFile);
    connect(ui->actionexit, &QAction::triggered, this, &MainWindow::exitSystem);
    connect(ui->actioncheck, &QAction::triggered, this, &MainWindow::startObjectCheck);
    connect(ui->actionabout, &QAction::triggered, this, &MainWindow::showAboutWindow);
    connect(ui->txtCheckContent, &QPlainTextEdit::blockCountChanged, this, &MainWindow::blockCountChanged);
    //关闭对象文件
    closeObjectFile();
}

void MainWindow::newObjectFile()
{
    ui->txtCheckContent->clear();
    ui->txtCheckContent->show();
}

void MainWindow::openObjectFile()
{
    //显示对话框
    QFileDialog *fileDialog = new QFileDialog(this, Qt::Dialog);
    QStringList fileFilters;
    fileFilters<<"对象文件(*.cls)";
    fileDialog->setNameFilters(fileFilters);
    if(fileDialog->exec()==QFileDialog::Accepted){
        //清空编辑框
        ui->txtCheckContent->clear();
        //获取文件路径
        QString filePath = fileDialog->selectedFiles().at(0);
        qDebug()<<filePath;
        QFile file(filePath);
        //打开对象文件
        if(!file.open(QIODevice::ReadOnly|QIODevice::Text)){
            QMessageBox::warning(this, "错误", "文件打开失败！");
            return;
        }
        qDebug()<<"Open file successful.";
        QByteArray buffer;
        QTextCodec *textCodec = QTextCodec::codecForName("UTF-8");
        while(!file.atEnd()){
            buffer = file.readLine();
            QString readLine = textCodec->toUnicode(buffer);
            ui->txtCheckContent->appendPlainText(readLine);
        }
        //显示编辑框
        ui->txtCheckContent->show();
        qDebug()<<"Read finished.";
    }
}

void MainWindow::closeObjectFile()
{
    ui->txtCheckContent->clear();
    ui->txtCheckContent->hide();
}

void MainWindow::exitSystem()
{
    auto btn = QMessageBox::question(this, "提示", "确定退出？", QMessageBox::Yes|QMessageBox::No);
    if(QMessageBox::Yes == btn){
        close();
    }
}

void MainWindow::startObjectCheck()
{
    //清空缓存
    m_defineList.clear();
    m_objectList.clear();
    m_objectStack.clear();
    //获取文本框内容
    QTextDocument* document = ui->txtCheckContent->document();
    const int lineCount = document->lineCount();
    //遍历所有行
    for(int lineIndex = 0; lineIndex < lineCount; lineIndex++){
        QString line = document->findBlockByLineNumber(lineIndex).text().trimmed();
        if(line.startsWith("#")){
            line = line.mid(1);
            if(line.startsWith(KEY_DEFINE)){
                QString temp = line.mid(strlen(KEY_DEFINE));
                QStringList params = temp.split("=");
                QString defineName = params.at(0).trimmed();
                QString defineValue = params.at(1).trimmed();
                if(defineName.isEmpty() || defineValue.isEmpty()){
                    QMessageBox::warning(this, "提示", "声明格式错误！");
                    return;
                }
                bool isNumber;
                defineValue.toDouble(&isNumber);
                if(!isNumber){
                    QMessageBox::warning(this, "提示", QString("常量【%1】的值非数字！").arg(defineName));
                    return;
                }
                m_defineList[defineName] = defineValue;
                //qDebug()<<"声明："<<QString("%1 => %2").arg(key, val);
                continue;
            }
            if(line.startsWith(KEY_OBJECT)){
                QStringList params = line.split("=");
                QString objectName = params.at(1).trimmed();
                //qDebug()<<"创建："<<objectName;
                m_objectStack.push(objectName);
                continue;
            }
            if(line.startsWith(KEY_END)){
                //qDebug()<<"结束："<<line;
                QStringList endParams = line.split(" ", QString::SkipEmptyParts);
                if(endParams[0] == KEY_END && endParams[1] == KEY_OBJECT){
                    m_objectStack.pop();
                }else{
                    QMessageBox::warning(this, "提示", "对象结束语法错误！");
                    return;
                }
                continue;
            }
            if(line.startsWith(KEY_ELEMENT)){
                if(m_objectStack.isEmpty()){
                    QMessageBox::warning(this, "提示", "未创建对象！");
                    return;
                }
                //获取当前对象名称
                QString objectName = m_objectStack.top();
                //去掉制表符“\t”
                line = line.replace("\t", "");
                //使用正则表达式进行拆分（空格或等号）
                QRegExp regExp(" |=");
                QStringList params = line.split(regExp, QString::SkipEmptyParts);
                if(params.size() % 2 != 0){
                    QMessageBox::warning(this, "提示", QString("对象【%1】的属性定义错误！").arg(objectName));
                    return;
                }
                //qDebug()<<"元素："<<params;
                //获取属性参数
                OBJECT_ELEMENT element;
                for (int i = 0; i < params.size(); i += 2) {
                    element[params[i]] = params[i + 1].trimmed();
                }
                //属性类型
                if(element.count(KEY_TYPE) > 0){
                    QString typeValue = element[KEY_TYPE];
                    if(typeValue.size() == 1){
                        QChar t = typeValue[0];
                        if(!((t >= 'a' && t <= 'z') || (t >= 'A' && t <= 'Z'))){
                            QMessageBox::warning(this, "提示", QString("对象【%1】的属性【%2】类型错误！").arg(objectName, element[KEY_ELEMENT]));
                            return;
                        }
                    }
                    if(typeValue.size() > 1){
                        QStringList typeParams = typeValue.split(",");
                        if(typeParams.size() != 2){
                            QMessageBox::warning(this, "提示", QString("对象【%1】的属性【%2】类型错误！").arg(objectName, element[KEY_ELEMENT]));
                            return;
                        }
                    }
                }
                //属性长度
                if(element.count(KEY_LENGTH) > 0){
                    QString elementLength = element[KEY_LENGTH];
                    if(elementLength.startsWith("$")){
                        elementLength = elementLength.mid(1);
                        if(m_defineList.count(elementLength) > 0){
                            elementLength = m_defineList[elementLength];
                            element[KEY_LENGTH] = elementLength;
                        }else{
                            QMessageBox::warning(this, "提示", QString("找不到【%1】常量！").arg(elementLength));
                            return;
                        }
                    }else{
                        bool isNumber;
                        elementLength.toDouble(&isNumber);
                        if(!isNumber){
                            QMessageBox::warning(this, "提示", QString("对象【%1】的属性【%2】长度错误！").arg(objectName, element[KEY_ELEMENT]));
                            return;
                        }
                    }
                }
                //获取对象属性列表
                OBJECT_ELEMENT_LIST elementList = m_objectList[objectName];
                //插入新的属性
                elementList[params[1]] = element;
                //更新对象属性列表
                m_objectList[objectName] = elementList;
                continue;
            }
        }
    }
    qDebug().noquote()<<"声明列表："<<m_defineList;
    qDebug().noquote()<<"对象列表："<<m_objectList;
    if(m_objectStack.isEmpty()){
        qDebug()<<"检测成功！";
        m_objectWindow = new ObjectWindow(m_defineList, m_objectList);
        m_objectWindow->show();
    }else{
        qDebug()<<"检测失败！";
        QMessageBox::warning(this, "提示", QString("对象定义格式错误！"));
        return;
    }
}

void MainWindow::showAboutWindow()
{
    m_aboutWindow = new AboutWindow(this);
    m_aboutWindow->setModal(true);
    m_aboutWindow->show();
}

void MainWindow::blockCountChanged(int newBlockCount)
{
    ui->statusbar->showMessage(QString("行数：%1").arg(newBlockCount));
}

